﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil.Cil;
using Mono.Cecil;

namespace devtm.Aop.Emit
{

    public class TryBlockCilWorker : CilWorker
    {

        private Label labelFinally;
        protected Instruction EndBlock;

        internal TryBlockCilWorker(CilWorker parent, Instruction firstTryInstruction, Instruction lastTryInstruction)
            : base(parent)
        {

            TryStart = cursor = firstTryInstruction;
            EndBlock = TryEnd = lastTryInstruction;

            labelFinally = DefineLabel();

            Instruction lst = Insert(OpCodes.Nop);

            InsertAfter(TryEnd, OpCodes.Nop);
            Insert(OpCodes.Leave_S, labelFinally);  // Jump finally

            TryStart = TryStart.Next;
            TryEnd = Parent.Current;
            EndBlock = cursor;
        }

        public Instruction TryStart { get; set; }


        public Instruction TryEnd { get; set; }


        //internal List<CatchBlockCilWorker> Catches = new List<CatchBlockCilWorker>();
        //public CatchBlockCilWorker AddCatch(Type exceptionType)
        //{
        //    CatchBlockCilWorker c = AddCatch(Body.Method.Module.Import(exceptionType));
        //    return c;
        //}


        //public CatchBlockCilWorker AddCatch(TypeReference exceptionType)
        //{

        //    //this.Parent
        //    CatchBlockCilWorker c = new CatchBlockCilWorker(this, EndBlock, exceptionType, labelFinally);

        //    Catches.Add(c);

        //    return c;

        //}


        //public FinallyBlockCilWorker Finally()
        //{

        //    Instruction lst = null;
        //    lst = EndBlock;

        //    foreach (CatchBlockCilWorker item in Catches)            
        //        lst = item.EndBlock;
            

        //    _Finally = new FinallyBlockCilWorker(Body, lst, labelFinally);

        //    return _Finally;

        //}

        //internal FinallyBlockCilWorker _Finally;

    }

}


/*
         
        [0] class [mscorlib]System.Exception ex)

t1      L_0001: nop
                // Instructions Try
            L_0008: nop
            L_0009: leave.s L_0016	->	goto label1
            L_000b: stloc.0
            L_000c: nop
                    // Instructions Cacht
            L_0013: nop
            L_0014: leave.s L_0016	->	goto label1

label1: L_0016: nop
        L_0017: leave.s L_0022	->	goto label2
t1      L_0019: nop
                // Instructions Finally
        L_0020: nop
        L_0021: endfinally

label2: L_0022: nop                                 

         
    .try L_0001 to L_000b catch [mscorlib]System.Exception handler L_000b to L_0016
    .try L_0001 to L_0019 finally handler L_0019 to L_0022

*/


/*
 
    L_0001: nop 
 
    L_0002: nop 
    L_0003: leave.s L_0008
    L_0005: nop 
    L_0006: nop 
    L_0007: endfinally 
    L_0008: nop 

    .try L_0001 to L_0005 finally handler L_0005 to L_0008

 * 
 */